home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-05-09 | 30.4 KB | 1,005 lines |
- -----------------------------------------------------------------------------
-
-
- WAIS Protocol Users Manual
-
-
- Release 1.0.1
-
-
- Harry Morris
- (morris@think.com)
- Thinking Machines Corporation
- 3.30.90
-
-
-
- 1.0 INTRODUCTION:
- 2.0 THE PROTOCOL ARCHITECTURE:
- 3.0 THE Z39.50 APDU LIBRARY:
- 4.0 THE Z39.50 UTILITY FUNCTIONS:
- 5.0 Z39.50 TYPE 1 QUERY
- 6.0 INTEGRATION OF WAIS AND Z39.50 LIBRARIES:
- 7.0 THE WAIS LIBRARY:
- 8.0 WAIS TYPE 1 QUERY:
- 9.0 IMPLEMENTATION NOTES:
- 10.0 WALK THROUGH OF INIT APDU:
- 11.0 WALK THROUGH OF WAIS INIT RESPONSE PROTOCOL EXTENSION:
- 12.0 WALK THROUGH OF SAMPLE APPLICATION:
- 13.0 ISSUES:
- 14.0 SPEC NOTES:
- 15.0 DISCLAIMER:
-
-
-
- 1.0 INTRODUCTION:
-
- The WAIS protocol is an extension to ANSI's Z39.50 protocol. The
- extensions are documented in "WAIS Intgerface Protocol Prototype
- Functional Specification Version 1.5" by Franklin Davis.
-
- This document describes an initial implementation of the protocol.
- The implementation is in ANSI C. It is provided in two libraries -
- the base Z39.50 library and the WAIS protocol libarary. The libraries
- define structures for each APDU and element set. Functions are
- provided to build, and destroy the structures. Each structure can
- also be written into a buffer and read from a buffer. The structure's
- representation in the buffer is defined in the specifications.
-
-
- 2.0 THE PROTOCOL ARCHITECTURE:
-
- The Z39.50 layer provides support for the basic APDU's, utility functions
- for manipulating tagged data, and hooks for use by the application layer.
-
- The WAIS protocol defines several structures which may be associated with
- APDU's. It also provides definitions of the Z39.50 hook functions, which
- allow the structures to be read and written.
-
- These layers specify the translation of an object (a C struct) to and from
- a memory buffer. The representation within the buffer is that defined in
- the Z.39.50 spec.
-
- It is the responsibility of application to construct, send, recieve, and
- destroy the Z39.50 and WAIS objects.
-
-
- 3.0 THE Z39.50 APDU LIBRARY:
-
- Six APDU's are currently defined: Init,InitResponse,Search,SearchResponse,
- Present,PresentResponse. Other APDU's will be added as time premits.
- The C definitions are direct translations of the structures outlined in
- appendix A of the Z39.50 spec. The following functions are provided to
- create, destroy, read, and write the respective APDU's.
-
-
- typedef struct InitAPDU {
- pdu_type PDUType;
- boolean willSearch,willPresent,willDelete;
- boolean supportAccessControl,supportResourceControl;
- long PreferredMessageSize;
- long MaximumRecordSize;
- char* IDAuthentication;
- char* ImplementationID;
- char* ImplementationName;
- char* ImplementationVersion;
- any* ReferenceID;
- void* UserInformationField;
- } InitAPDU;
-
- InitAPDU* makeInitAPDU(
- boolean search,boolean present,boolean delete,
- boolean accessControl,boolean resourceControl,
- long prefMsgSize,long maxMsgSize,
- char* auth,char* id,char* name, char* version,
- any* refID,any* userInfo);
-
- void freeInitAPDU(InitAPDU* init);
-
- void writeInitAPDU(InitAPDU* init,char* buffer);
-
- InitAPDU* readInitAPDU(char* buffer);
-
-
- typedef struct InitResponseAPDU {
- pdu_type PDUType;
- boolean Result;
- boolean willSearch,willPresent,willDelete;
- boolean supportAccessControl,supportResourceControl;
- long PreferredMessageSize;
- long MaximumRecordSize;
- char* IDAuthentication;
- char* ImplementationID;
- char* ImplementationName;
- char* ImplementationVersion;
- any* ReferenceID;
- void* UserInformationField;
- } InitResponseAPDU;
-
- InitResponseAPDU* makeInitResponseAPDU(
- boolean result,
- boolean search,boolean present,boolean delete,
- boolean accessControl,boolean resourceControl,
- long prefMsgSize,long maxMsgSize,
- char* auth,char* id,char* name, char* version,
- any* refID,any* userInfo);
-
- void freeInitResponseAPDU(InitResponseAPDU* init);
-
- void writeInitResponseAPDU(InitResponseAPDU* init,char* buffer);
-
- InitResponseAPDU* readInitResponseAPDU(char* buffer);
-
- InitResponseAPDU* replyToInitAPDU(InitAPDU* init,boolean result,
- any* userInfo);
- This is a convienience function to create a default InitResponse
- given a response.
-
-
- typedef struct SearchAPDU {
- pdu_type PDUType;
- long SmallSetUpperBound;
- long LargeSetLowerBound;
- long MediumSetPresentNumber;
- boolean ReplaceIndicator;
- char* ResultSetName;
- char** DatabaseNames;
- char* QueryType;
- char** ElementSetNames;
- any* ReferenceID;
- void* Query;
- } SearchAPDU;
-
- SearchAPDU* makeSearchAPDU(
- long small,long large, long medium,
- boolean replace,char* name,char** databases,char* type,
- char** elements,any* refID,any* queryInfo);
-
- void freeSearchAPDU(SearchAPDU* query);
-
- void writeSearchAPDU(SearchAPDU* query,char* buffer);
-
- SearchAPDU* readSearchAPDU(char* buffer);
-
-
- typedef struct SearchResponseAPDU {
- pdu_type PDUType;
- long SearchStatus;
- long ResultCount;
- long NumberOfRecordsReturned;
- long NextResultSetPosition;
- long ResultSetStatus;
- long PresentStatus;
- any* ReferenceID;
- void* DatabaseDiagnosticRecords;
- } SearchResponseAPDU;
-
- SearchResponseAPDU* makeSearchResponseAPDU(
- boolean result,long count,
- long recordsReturned,long nextPos,
- long resultStatus,long presentStatus,
- any* refID,any* records);
-
- void freeSearchResponseAPDU(SearchResponseAPDU* queryResponse);
-
- void writeSearchResponseAPDU(SearchResponseAPDU* queryResponse,
- char* buffer);
-
- SearchResponseAPDU* readSearchResponseAPDU(char* buffer);
-
-
- typedef struct PresentAPDU {
- pdu_type PDUType;
- long NumberOfRecordsRequested;
- long ResultSetStartPosition;
- char* ResultSetID;
- char* ElementSetNames;
- any* ReferenceID;
- void* PresentInfo; /* XXX not in Z39.50 spec !!! */
- } PresentAPDU;
-
- PresentAPDU* makePresentAPDU(long recsReq, long startPos,
- char* resultID,any* refID,void* info);
-
- void freePresentAPDU(PresentAPDU* present);
-
- void writePresentAPDU(PresentAPDU* present,char* buffer);
-
- PresentAPDU* readPresentAPDU(char* buffer);
-
-
- typedef struct PresentResponseAPDU {
- pdu_type PDUType;
- boolean PresentStatus;
- long NumberOfRecordsReturned;
- long NextResultSetPosition;
- any* ReferenceID;
- void* DatabaseDiagnosticRecords;
- } PresentResponseAPDU;
-
- PresentResponseAPDU* makePresentResponseAPDU(boolean status,
- long recsRet,long nextPos,any* refID,any* records);
-
- void freePresentResponseAPDU(PresentResponseAPDU* present);
-
- void writePresentResponseAPDU(PresentResponseAPDU* present,char* buffer);
-
- PresentResponseAPDU* readPresentResponseAPDU(char* buffer);
-
-
-
- 4.0 THE Z39.50 UTILITY FUNCTIONS:
-
- The utility functions implement the core Z39.50 datatypes. They are
- used internaly by the Z39.50 APDU library functions, and can be used
- to implement "user information" fields. They are divided into four
- categories:
-
- 1. Tagged Data Functions - these functions operate on tagged data.
- They are available for use in "user information" fields.
-
- 2. Raw Data Functions - these functions are used to implement the
- tagged data functions, and the fixed area of each APDU. They
- are should not be used for "user information".
-
- 3. Version Functions - these functions provide default definitions
- for the optional version fields.
-
- 4. Utility Functions.
-
- Tagged Data Functions:
-
- typedef struct any { /* an any is a non-ascii string of characters */
- unsigned long size;
- char* bytes;
- } any;
-
- any* makeAny(unsigned int size,char* data);
- void freeAny(any* a);
- any* duplicateAny(any* a);
- char* writeAny(any* a,data_tag tag,char* buffer);
- char* readAny(any** anAny,char* buffer);
- unsigned long writtenAnySize(any* a);
-
- typedef any bit_map; /* a bit_map is a group of packed bits */
-
- bit_map* makeBitMap(int numBits,...);
- The variable arguments are boolean "bits".
- void freeBitMap(bit_map* bm);
- boolean bitAtPos(int pos,bit_map* bm);
- char* writeBitMap(bit_map* bm,data_tag tag,char* buffer);
- char* readBitMap(bit_map** bm,char* buffer);
-
- char* writeNum(long num,data_tag tag,char* buffer);
- char* readNum(long* num,char* buffer);
-
- char* writeString(char* s,data_tag tag,char* buffer);
- char* readString(char** s,char* buffer);
- These are convienience functions that can be used anywhere an
- Any is called for.
-
-
- Raw Data Functions:
-
- char* writeCompressedInteger(unsigned int num,char* buf);
- char* readCompressedInteger(unsigned int *num,char* buf);
- char* writeCompressedIntegerWithPadding(unsigned long num,
- unsigned int size,char* buffer);
- unsigned long writtenCompressedIntSize(unsigned long num);
- Compressed Integers are described on p. XXX of the Z39.50 document.
-
-
- typedef unsigned long data_tag;
-
- char* writeTag(data_tag tag,char* buf);
- char* readTag(data_tag* tag,char* buf);
- data_tag peekTag(char* buf);
- unsigned long writtenTagSize(data_tag tag);
-
- char* writeByte(unsigned char byte,char* buf);
- char* readByte(unsigned char* byte,char* buf);
-
- char* writeBoolean(boolean flag,char* buf);
- char* readBoolean(boolean* flag,char* buf);
-
- typedef unsigned long pdu_type;
-
- char* writePDUType(pdu_type pduType,char* buf);
- char* readPDUType(pdu_type* pduType,char* buf);
- pdu_type peekPDUType(char* buf);
-
- char* writeBinaryInteger(long num,unsigned int size,char* buf);
- char* readBinaryInteger(long* num,unsigned int size,char* buf);
- unsigned long writtenCompressedBinIntSize(long num);
-
-
- Version Functions:
-
- char* writeProtocolVersion(char* buf);
- Writes the version of the Z39.50 spec that is implemented.
- This implementation is version 1.
-
- char* defaultImplementationID(void);
- char* defaultImplementationName(void);
- char* defaultImplementationVersion(void);
- These functions write default information as suggested by the
- implementers of the protocol. The application may override
- these fields.
-
-
- Utility Functions:
-
- doList(void** list,void (*func)());
-
-
- 5.0 Z39.50 TYPE 1 QUERY
-
- The Z39.50 specification defines a type one query as a series of terms, each
- of which is of type Attribute, ResultsSet, or Operator. The the Attribute
- terms bind a variable in the current data base (eg. Author = E.A.Poe). The
- ResultSet terms specify a subset of the database. They are used to store
- intermediate results. The Operator terms specify an operation relating
- Attribute and ResultSet terms (eg. Author = E.A.Poe AND Publisher =
- McGraw-Hill). The terms are gathered on a stack, and evaluated in RPN
- order. Results are left on the stack for return to the calling program.
- The following code defines a query term and provides functions for writing
- and reading terms and lists of terms.
-
- typedef struct query_term {
- /* type */
- int TermType;
- /* for term */
- char Use[ATTRIBUTE_SIZE];
- char Relation[ATTRIBUTE_SIZE];
- char Position[ATTRIBUTE_SIZE];
- char Structure[ATTRIBUTE_SIZE];
- char Truncation[ATTRIBUTE_SIZE];
- char Completeness[ATTRIBUTE_SIZE];
- any* Term;
- /* for result set */
- any* ResultSetID;
- /* for operator */
- char Operator[OPERATOR_SIZE];
- } query_term;
-
- query_term* makeAttributeTerm(
- char* use,char* relation,char* position,char* structure,
- char* truncation,char* completeness,any* term);
- query_term* makeResultSetTerm(any* resultSet);
- query_term* makeOperatorTerm(char* operator);
- void freeTerm(query_term* qt);
- char* writeQueryTerm(query_term* qt,char* buffer);
- char* readQueryTerm(query_term** qt,char* buffer);
- any* writeQuery(query_term** terms);
- query_term** readQuery(any* info);
-
-
-
- 6.0 INTEGRATION OF WAIS AND Z39.50 LIBRARIES:
-
- The WAIS protocol is implemented through the "user information" field of
- Z39.50's APDU's. Each Z39.50 APDU has a pointer to user information, and
- a hook function to read and write the information.
-
- The functions are:
-
- extern char* writeInitInfo(InitAPDU* init,char* buffer);
- extern char* readInitInfo(void** info,char* buffer);
-
- extern char* writeInitResponseInfo(InitResponseAPDU* init,char* buffer);
- extern char* readInitResponseInfo(void** info,char* buffer);
-
- extern char* writeSearchInfo(SearchAPDU* query,char* buffer);
- extern char* readSearchInfo(void** info,char* buffer);
-
- extern char* writeSearchResponseInfo(SearchResponseAPDU* query,
- char* buffer);
- extern char* readSearchResponseInfo(void** info,char* buffer);
-
- extern char* writePresentInfo(PresentAPDU* present,char* buffer);
- extern char* readPresentInfo(void** info,char* buffer);
-
- extern char* writePresentResponseInfo(PresentResponseAPDU* present,
- char* buffer);
- extern char* readPresentResponseInfo(void** info,char* buffer);
-
- The write functions are called after writing the standard APDU, and only if
- the user information field is not NULL. The read functions are called
- after reading the standard APDU. They should return NULL if there is no
- user information, otherwise they should use the Z39.50 utility functions
- to reconstruct the user information as it was written.
-
-
- 7.0 THE WAIS LIBRARY:
-
- The WAIS library is devided into two parts. The first part defines
- structures and code to manipulate the WAIS components which are directly
- mapped to Z39.50 APDUs. The second part defines component structures
- which are used by the WAIS protocol to pass specific elements between the
- origin and target. Note that all objects of the first type also provide
- implementations of the read and write functions described in section 6.0.
-
-
- Basic WAIS Components:
-
-
- typedef struct WAISInitResponse {
- long ChunkCode;
- long ChunkIDLength;
- char* ChunkMarker;
- char* HighlightMarker;
- char* DeHighlightMarker;
- char* NewlineCharacters;
- /* XXX need to add UpdateFrequency and Update Time */
- } WAISInitResponse;
-
- WAISInitResponse* makeWAISInitResponse(
- long chunkCode,long chunkIDLen,char* chunkMarker,
- char* highlightMarker,
- char* deHighlightMarker,char* newLineChars);
- void freeWAISInitResponse(WAISInitResponse* init);
-
-
- typedef struct WAISSearch {
- char* SeedWords;
- DocObj** Docs;
- char** TextList;
- long DateFactor;
- char* BeginDateRange;
- char* EndDateRange;
- long MaxDocumentsRetrieved;
- } WAISSearch;
-
- WAISSearch* makeWAISSearch(
- char* seedWords,DocObj** docs,char** textList,
- long dateFactor,char* beginDateRange,char* endDateRange,
- long maxDocsRetrieved);
- void freeWAISSearch(WAISSearch* query);
-
-
- typedef struct WAISSearchResponse {
- char* SeedWordsUsed;
- WAISDocumentHeader** DocHeaders;
- WAISDocumentShortHeader** ShortHeaders;
- WAISDocumentLongHeader** LongHeaders;
- WAISDocumentText** Text;
- WAISDocumentHeadlines** Headlines;
- WAISDocumentCodes** Codes;
- } WAISSearchResponse;
-
- WAISSearchResponse* makeWAISSearchResponse(
- char* seedWordsUsed,WAISDocumentHeader** docHeaders,
- WAISDocumentShortHeader** shortHeaders,
- WAISDocumentLongHeader** longHeaders,
- WAISDocumentText** text,WAISDocumentHeadlines** headlines,
- WAISDocumentCodes** codes);
- void freeWAISSearchResponse(WAISSearchResponse* response);
-
-
- typedef struct WAISPresent {
- DocObj** Documents; /* type of request is in element set */
- } WAISPresent;
-
- WAISPresent* makeWAISPresent(DocObj** docs);
- void freeWAISPresent(WAISPresent* present);
-
-
- typedef struct WAISPresentResponse {
- WAISDocumentText** Text;
- WAISDocumentHeadlines** Headlines;
- WAISDocumentCodes** Codes;
- } WAISPresentResponse;
-
- WAISPresentResponse* makeWAISPresentResponse(WAISDocumentText** text,
- WAISDocumentHeadlines** headlines,
- WAISDocumentCodes** codes);
- void freeWAISPresentResponse(WAISPresentResponse* response);
-
-
- WAIS Elements:
-
-
- typedef struct DocObj { /* specifies a section of a document */
- any* DocID;
- long ChunkCode;
- union {
- long Pos;
- any* ID;
- } ChunkStart;
- union {
- long Pos;
- any* ID;
- } ChunkEnd;
- } DocObj;
-
- DocObj* makeDocObjUsingWholeDocument(any* docID);
- DocObj* makeDocObjUsingBytes(any* docID,long start,long end);
- DocObj* makeDocObjUsingLines(any* docID,long start,long end);
- DocObj* makeDocObjUsingParagraphs(any* docID,any* start,any* end);
- void freeDocObj(DocObj* doc);
- Note that DocObjs are used read and written internally.
-
-
- typedef struct WAISDocumentHeader {
- any* DocumentID;
- long VersionNumber;
- long Score;
- long BestMatch;
- long DocumentLength;
- long Lines;
- char* Source;
- char* Date;
- char* Headline;
- char* OriginCity;
- } WAISDocumentHeader;
-
- WAISDocumentHeader* makeWAISDocumentHeader(
- any* docID,long versionNumber,long score,long bestMatch,long docLen,
- long lines,char* source,char* date,char* headline,char* originCity);
- void freeWAISDocumentHeader(WAISDocumentHeader* header);
- char* writeWAISDocumentHeader(WAISDocumentHeader* header,char* buffer);
- char* readWAISDocumentHeader(WAISDocumentHeader** header,char* buffer);
-
-
- typedef struct WAISDocumentShortHeader {
- any* DocumentID;
- long VersionNumber;
- long Score;
- long BestMatch;
- long DocumentLength;
- long Lines;
- } WAISDocumentShortHeader;
-
- WAISDocumentShortHeader* makeWAISDocumentShortHeader(
- any* docID,long versionNumber,long score,long bestMatch,
- long docLen,long lines);
- void freeWAISDocumentShortHeader(WAISDocumentShortHeader* header);
- char* writeWAISDocumentShortHeader(WAISDocumentShortHeader* header,
- char* buffer);
- char* readWAISDocumentShortHeader(WAISDocumentShortHeader** header,
- char* buffer);
-
-
- typedef struct WAISDocumentLongHeader {
- any* DocumentID;
- long VersionNumber;
- long Score;
- long BestMatch;
- long DocumentLength;
- long Lines;
- char* Source;
- char* Date;
- char* Headline;
- char* OriginCity;
- char* StockCodes;
- char* CompanyCodes;
- char* IndustryCodes;
- } WAISDocumentLongHeader;
- WAISDocumentLongHeader* makeWAISDocumentLongHeader(
- any* docID,long versionNumber,long score,long bestMatch,long docLen,
- long lines,char* source,char* date, char* headline,char* originCity,
- char* stockCodes,char* companyCodes,char* industryCodes);
- void freeWAISDocumentLongHeader(WAISDocumentLongHeader* header);
- char* writeWAISDocumentLongHeader(WAISDocumentLongHeader* header,
- char* buffer);
- char* readWAISDocumentLongHeader(WAISDocumentLongHeader** header,
- char* buffer);
-
-
- typedef struct WAISDocumentText {
- any* DocumentID;
- long VersionNumber;
- any* DocumentText;
- } WAISDocumentText;
-
- WAISDocumentText* makeWAISDocumentText(any* docID,long versionNumber,
- any* documentText);
- void freeWAISDocumentText(WAISDocumentText* docText);
- char* writeWAISDocumentText(WAISDocumentText* docText,char* buffer);
- char* readWAISDocumentText(WAISDocumentText** docText,char* buffer);
-
-
- typedef struct WAISDocumentHeadlines {
- any* DocumentID;
- long VersionNumber;
- char* Source;
- char* Date;
- char* Headline;
- char* OriginCity;
- } WAISDocumentHeadlines;
-
- WAISDocumentHeadlines* makeWAISDocumentHeadlines(
- any* docID,long versionNumber,char* source,char* date,
- char* headline,char* originCity);
- void freeWAISDocumentHeadlines(WAISDocumentHeadlines* docHeadline);
- char* writeWAISDocumentHeadlines(WAISDocumentHeadlines* docHeadline,
- char* buffer);
- char* readWAISDocumentHeadlines(WAISDocumentHeadlines** docHeadline,
- char* buffer);
-
-
- typedef struct WAISDocumentCodes {
- any* DocumentID;
- long VersionNumber;
- char* StockCodes;
- char* CompanyCodes;
- char* IndustryCodes;
- } WAISDocumentCodes;
-
- WAISDocumentCodes* makeWAISDocumentCodes(
- any* docID,long versionNumber,char* stockCodes,char* companyCodes,
- char* industryCodes);
- void freeWAISDocumentCodes(WAISDocumentCodes* docCodes);
- char* writeWAISDocumentCodes(WAISDocumentCodes* docCodes,char* buffer);
- char* readWAISDocumentCodes(WAISDocumentCodes** docCodes,char* buffer);
-
-
- 8.0 WAIS TYPE 1 QUERY
-
- The WAIS Protocol used type one queries to retrieve fragments of text from
- the target. The syntax is:
-
- 1. retrieve the header/codes from a document:
-
- System_Control_Number = docID (attribute)
-
- return type is dependent on element set requested
-
- 2. retrieve a fragment of the text of a document:
-
- System_Control_Number = docID (attribute)
- Chunk >= start (attribute)
- And (operator)
- Chunk < end (attribute)
- And (operator)
-
- return type is always WAISDocumentText
-
- Information from multiple documents may be requested by using
- groups of the above joined by:
-
- OR (operator)
-
- The following functions translate between list of DocObjs and an any
- containing the DocObjs written in the form given above.
-
- any* makeWAISType1Query(DocObj** docs);
- DocObj** readWAISType1Query(any* terms);
-
-
- 9.0 IMPLEMENTATION NOTES:
-
- Z39.50 Types:
-
- ANY - Implemented as a structure containing a size field and
- an arbitrary length block of bytes. Value is NULL if
- the element is not present.
-
- ASCII - Implemented as a C string (null terminated).
- Value is NULL if the element is not present.
-
- BitMap - Implemented as an any, with packed bits. Value is NULL
- if the element is not present.
-
- Data Tag - Implemented as an unsigned int.
-
- PduType - Implemented as an enum.
-
- Binary Integer - implemented as a long. Value is UNUSED if the
- element is not present.
-
-
- Memory Mangement:
-
- Memory management is fairly simple. The idea is to minimize the
- copying of large (application specific) data (eg. text buffers),
- while minimizing the amount of explicit freeing that must be
- done by the user of the protocol.
-
- Calls to makeFoo() always copy small arguments and simply reference
- large arguments. All Z39.50 APDU's are small, so they always copy.
- All WAIS objects are large, so they always reference.
-
- Calls to freeFoo() always free all elements of foo.
-
- What this means to you:
-
- 1. When making and APDU, be sure to free the arguments (an easy way
- to do this is to use automatic arguments).
-
- 2. When making a WAIS object, don't free the arguments (don't use
- automatic arguments).
-
- 3. If you want to hold onto part of an object that is about to be
- freed, make a pointer to the part, and NULL out the pointer
- in the object.
-
- This is much harder to explain than to do. Study the example code
- and/or call the author if you have questions.
-
-
- 10.0 WALK THROUGH OF INIT APDU:
-
- The Init APDU is a typical of the Z39.50 APDU's. The pseudo code for its
- functions is presented here.
-
-
- makeInitAPDU(boolean willSearch,boolean willPresent,boolean willDelete,
- boolean supportAccessControl,
- boolean supportResourceControl,
- int preferredMessageSize,int maxMessageSize,
- string authorization,string identification,
- string implementationName,string implementationVersion,
- any referenceID,pointer userInformation)
-
- { Allocate space for an init APDU.
-
- Assign it values based on the arguments. This may involve checking
- that all required arguments are there, and making copies of some
- arguments.
-
- Return the new APDU.
- }
-
-
- freeInitAPDU(InitAPDU init)
-
- { Deallocate any arguments that were copied in makeInitAPDU().
-
- Deallocate the APDU itself.
- }
-
-
- writeInitAPDU(InitAPDU init,memoryBuffer buffer)
-
- { Declare a pointer buf pointing into buffer, starting HEADER_LEN
- bytes in.
-
- Write init's PDUType at buf, and set buf to the end of the write.
-
- Write the rest of init's data, doing any conversions necessary.
-
- Record the size of APDU (buf - buffer) in the first HEADER_LEN
- bytes of buffer.
-
- Call writeInitInfo() to write user information into the buffer.
- }
-
-
- readInitAPDU(memoryBuffer buffer)
-
- { Declare a pointer buf pointing into the begining of buffer.
-
- Declare local variables for the elements of the APDU.
-
- Read the APDU's size (stored in the first HEADER_LEN bytes).
-
- Read the APDU elements that are reqired to be there.
-
- Decode the ones which are packed (bitmaps)
-
- While buf is less that (buffer + size + HEADER_LEN)
- { Read the next tag.
-
- Based on the value of the tag, read in an optional element.
-
- Increment buf by the size of the element.
- }
-
- Call readInitInfo() to read user information from the buffer.
-
- Call makeInitAPDU() to create an init APDU.
-
- Deallocate any local variables.
-
- Return the new init APDU.
- }
-
-
- 11.0 WALK THROUGH OF WAIS INIT RESPONSE PROTOCOL EXTENSION:
-
- The WAIS Init Response is a typical of the Z39.50 protocol extension.
- The pseudo code for its functions is presented here. It is essentially
- identical to that of any of the Z39.50 APDU's. Note that the reading and
- writing routines are Z39.50 hooks.
-
-
- makeWAISInitResponse(int chunkCode,int chunkIDLen,string chunkMarker,
- string highlightMarker,string deHighlightMarker,
- string newLineChars)
-
- { Allocate space for an init response.
-
- Assign it values based on the arguments. This may involve checking
- that all required arguments are there, and making copies of some
- arguments.
-
- Return the new response object.
- }
-
-
- freeWAISInitResponse(WAISInitResponse response)
-
- { Deallocate any arguments that were copied in makeWAISInitResponse().
-
- Deallocate the response itself.
- }
-
-
- writeInitResponseInfo(InitResponseAPDU responseAPDU,memoryBuffer buffer)
-
- { Declare a pointer response pointing at the user information field
- of responseAPDU.
-
- Estimate the size of the written representation in bytes. Determine
- how many bytes are needed to represent that size (round up). Add
- the size of a tag field, and the size of the size field (always 1).
- This is the WAIS_HEADER_LEN.
-
- Declare a pointer buf pointing into buffer, starting WAIS_HEADER_LEN
- bytes in.
-
- Write the response's data at buf, doing any conversions necessary.
-
- Record the size of response's size (buf - buffer) in the first
- WAIS_HEADER_LEN bytes of buffer.
- }
-
-
- readInitResponseInfo(memoryBuffer buffer)
-
- { Declare a pointer buf pointing into the begining of buffer.
-
- Declare local variables for the elements of the response.
-
- Read the response's size (the first element).
-
- While buf is less that (buffer + size)
- { Read the next tag.
-
- Based on the value of the tag, read in an element.
-
- Increment buf by the size of the element.
- }
-
- Call makeWAISInitResponse() to create an response object.
-
- Deallocate any local variables.
-
- Return the new response object.
- }
-
-
- 12.0 WALK THROUGH OF SAMPLE APPLICATION:
-
- This section outlines how an application may play the role of origin or
- target. The pseudo code will be the same for every APDU.
-
-
- requestText(document,startLine,endLine) (for example)
-
- { Call makeWAISPresent(document,startLine,endLine) to construct a
- WAIS present object.
-
- Call makePresentAPDU(<z39.50 args>,WAISpresent) to construct a
- z39.50 present APDU with WAIS present object as its user
- information.
-
- Call writePresentAPDU(presentAPDU,buffer) to write the APDU and the
- user information to the buffer.
-
- Send the buffer to the target over whatever transport mechanism is
- available.
-
- Free the objects, or store them for future use.
- }
-
-
- recieveAPDU(buffer)
-
- { Call peekPDUType(buffer) to determine which APDU is in the buffer.
-
- Switch on the result to the appropriate reading routines:
-
- if pdu = initResponseAPDU
- apdu := readInitAPDU(buffer)
-
- else if pdu = searchResponseAPDU
- apdu := readSearchResponseAPDU(buffer)
-
- else if pdu = presentResponseAPDU
- apdu := readPresentResponseAPDU(buffer)
-
- Process the response.
-
- Free the apdu.
- }
-
-
- 13.0 ISSUES:
-
- The following are some of the open issues which we are still working on
- This is not necessarily a complete set. If you think of more, or
- have suggestions on how to approach these, please don't hesitate to contact
- the author.
-
- - The following parts are defined in the WAIS Protocol Spec 1.5, but are
- not yet supported in the libraries: Chunk negotiation
-
-
- - Although the Present and PresentResponse APDUs (and their matching WAIS
- elements) are defined, they are not officially part of the WAIS protocol
- library, and as such they have not been fully implemented/tested.
-
- - The Z39.50 spec does not define the concrete representation of the Present
- Response APDU. The structure defined here is a straigtforward translation
- of the abstract representation.
-
- - The spec does not provide for a user information field in the Present
- APDU. We have added one, and believe it should be made a standard part of the
- spec.
-
- - We do not check to ensure that the refID fields are limited to 64
- characters as outlined in the spec.
-
- - We do nothing to respect MaximumRecordSize
-
- - Fix up naming conventions - should all these functions be prefixed with
- "Z3950_" to prevent name collisions?
-
- - Add support for other apdu's.
-
- - Check consistency with spec.
-
- - Test portability to other platforms - Partial port to Saber-C on Sun
- platforms is successful.
-
- - We need a way for servers to indicate what chunk sizes they will support.
- This could be done in the init/initResponse APDUs by passing a bitmap
- with the bit at possition N specifying the availablity of chunk size N.
- There are other difficulties with Chunks that the are under consideration
- at Thinking Machines.
-
- - The use of malloc will contribute to fragmentation of the heap which
- may be unacceptable on machines w/o virtual memory (macs). We may
- need a more abstract memory model.
-
-
- 14.0 SPEC NOTES:
-
- There are several issues alluded to in the spec that are not directly
- addressed. They are discussed here.
-
- - The size of a Binary integer is unspecified. We have chosen to use C long
- ints (4 bytes). When writing them in a variable section, we use only as
- many bytes as are required to represent their data.
-
-
- 14.0 DISCLAIMER:
-
- The libraries described here are initial implementations and are
- subject to change. We will make every effort to stabilize the
- libraries as soon as possible, and to inform all users of changes.
-
- One of our first goals will be to confirm that the implementation
- actually conforms to the Z39.50 specification. The WAIS protocol
- will undoubtably evolve over time as we gain experience with developing
- information servers and clients.
-
- These libraries will be placed in the public domain as soon as they
- are suitably stable. Until Thinking Machines releases the libraries,
- please do not distribute the libraries without first contacting the
- author.
-
- As always, if there is a discrepancy between the documentation and the
- code - believe the code.
-
-
-
-
- 01234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-
-
-
-